<template>
    <div class="btn-form" @touchmove="handleTouchMove">
        <van-popup v-model:show="showPopup" position="bottom" @open="openForm" :style="{ height: '100%' }">
            <!-- 标题 -->
            <van-nav-bar :title="statusType ? '留言' : BTN_TYPE[btnType.name]?.title" left-text="返回" left-arrow
                @click-left="showPopup = false" />

            <!-- 表单 -->
            <van-form @submit="onSubmit" ref="formRef" class="detailForm">
                <!-- 按钮新增 -->
                <template v-if="!statusType">
                    <van-cell-group inset>
                        <van-field v-model="form.to_username" label="To" placeholder="点击选择抄送人"
                            :rules="[{ required: BTN_TYPE[btnType.name]?.toRequired, message: '请选择担当人' }]"
                            :required="BTN_TYPE[btnType.name]?.toRequired" :is-link="BTN_TYPE[btnType.name]?.toRequired"
                            @click="toClick('to')">
                            <template #input>
                                <div v-if="!form.to_username" style="color: #9093a5;">点击选择担当人
                                </div>
                                <div v-else>{{ form.to_username }}</div>
                            </template>
                        </van-field>

                        <van-field label="CC" placeholder="点击选择抄送人" is-link>
                            <template #input>
                                <div @click="toClick('cc')">{{
                                    form.cc_users_name ? form.cc_users_name : '点击选择抄送人' }}
                                </div>
                            </template>
                        </van-field>

                        <template v-if="BTN_TYPE[btnType.name]?.timeRequired">
                            <van-field v-model="form.due_time" is-link readonly name="picker" label="截至时间"
                                placeholder="请选择截止时间" @click="showPicker = true" />
                            <van-popup v-model:show="showPicker" destroy-on-close position="bottom" @open="openPopup">
                                <van-picker-group v-model:active-tab="activeTab" title="预约日期" :tabs="['选择日期', '选择时间']"
                                    @confirm="onConfirm" @cancel="showPicker = false">
                                    <van-date-picker v-model="currentDate" :min-date="minDate" :max-date="maxDate" />
                                    <van-time-picker v-model="currentTime" :columns-type="['hour', 'minute', 'second']"
                                        :min-hour="computedTime('hour')" :min-minute="computedTime('minute')" />
                                </van-picker-group>
                            </van-popup>
                        </template>

                        <van-field v-model.trim="form.trust_ref_no" label="TRUST编号" placeholder="请填写TRUST编号"
                            maxlength="20" v-if="BTN_TYPE[btnType.name]?.trustRequired && !ticketInfo.ticket_type" />

                        <van-field v-model="form.reason_type_name" is-link label="原因类别" placeholder="请选择"
                            :rules="[{ required: BTN_TYPE[btnType.name]?.causeRequired, message: '选择原因类别' }]"
                            :required="BTN_TYPE[btnType.name]?.causeRequired" @click="workTypeShow = true" readonly
                            v-if="BTN_TYPE[btnType.name]?.causeType && !ticketInfo.ticket_type">
                            <template #input>
                                <van-popover v-model:show="workTypeShow" :actions="causeSelectActions"
                                    @select="onSelect">
                                    <template #reference>
                                        <div style="color: #d9d9d9;font-weight: 600;" v-if="!form.reason_type_name">
                                            请选择
                                        </div>

                                        <div v-else>{{ form.reason_type_name }}</div>
                                    </template>
                                </van-popover>
                            </template>
                        </van-field>

                        <template v-if="BTN_TYPE[btnType.name]?.scoreRequired">
                            <div class="scores-title">
                                确认对策后，此工单将被关闭。请对我们的服务进行评价。
                            </div>
                            <van-field v-model="form.reason_type_name" label="评分" placeholder="请选择"
                                :rules="[{ required: true, message: '请选择评分' }]" required>
                                <template #input>
                                    <div class="list-item-rate">
                                        <van-rate v-model="form.scores" :size="16" color="#ffd21e" void-icon="star"
                                            void-color="#eee" />
                                        <div style="padding-left: 10px">{{ scoresName[form.scores] }}</div>
                                    </div>
                                </template>
                            </van-field>
                        </template>

                        <van-field v-model="form.comment" autosize label="说明" type="textarea" maxlength="1000"
                            placeholder="请输入说明" show-word-limit
                            :rules="[{ required: BTN_TYPE[btnType.name]?.illustrateRequired, message: '选择原因类别' }]"
                            :required="BTN_TYPE[btnType.name]?.illustrateRequired" />

                    </van-cell-group>
                </template>

                <!-- 留言新增 -->
                <template v-else>
                    <van-field label="公开范围" class="left-uploader" :rules="[{ required: true, message: '请选择公开范围' }]"
                        required v-if="visible">
                        <template #input>
                            <van-radio-group v-model="form.is_public" direction="horizontal">
                                <van-radio :name="0" icon-size="14px">社内</van-radio>
                                <van-radio :name="1" icon-size="14px">社外</van-radio>
                            </van-radio-group>
                        </template>
                    </van-field>

                    <van-field v-model="form.appraise" rows="4" autosize label="留言" type="textarea" maxlength="1000"
                        placeholder="请填写留言" show-word-limit class="left-uploader"
                        :rules="[{ required: true, message: '请填写留言' }]" required />

                    <van-field name="uploader" label="附件" v-if="!visible" class="left-uploader">
                        <template #input>
                            <van-uploader :max-count="5"
                                accept=".docx,.xlsx,.pptx,.txt,.pdf,.jpg,.png,.zip,.xls,.xlsm,.doc,.docm,.ppt,.pptm,.pps"
                                :after-read="afterRead">
                                <div class="work-uploader">上传...</div>
                            </van-uploader>
                        </template>
                    </van-field>

                    <template v-for="item in form.attachment" :key="item.file_path">
                        <div class="work-file">
                            <div class="work-file-name" @click="previewFile(item)">{{ item.file_name }}</div>
                            <div @click="deleteFile(item.file_path)"><van-icon name="cross" /></div>
                        </div>
                    </template>
                </template>

                <div style="margin: 16px;">
                    <van-button round block type="primary" native-type="submit" color="#bf1920">
                        提交
                    </van-button>
                </div>

                <!-- 详情展示 -->
                <detailSubassembly button-type="2" />
            </van-form>


            <!-- 通讯录 -->
            <ContactsPopUp v-model="contactsShow" :parameter="parameter" operate_type="transfer"
                :ticket_number="ticketNumber" :commonly-id="commonlyId" :commonly-list-id="commonlyListId"
                @radioChange="radioChange" @checkboxChange="checkboxChange" />
        </van-popup>
    </div>
</template>

<script setup lang='ts'>
import dayjs from 'dayjs'
import { useRoute } from 'vue-router';
import { BTN_TYPE } from '@/enum/clientType'
import { download } from '@/utils/downloadUrl';
import useKeyboard from '@/utils/keyboard';
import detailSubassembly from './detailSubassembly.vue'
import ContactsPopUp from '@/components/ContactsPopUp.vue'
import { ButtonType, CommonlyType, EditAddType, TicketInfoType } from '@/api/worksheets/type';
import { workAttachmentDownload, workAttachmentUpload, workOrderSure, workSure } from '@/api/worksheets';

const prop = defineProps<{
    statusType: number //0-按钮新增 1-留言
    btnType: ButtonType//按钮回显数据
    ticketInfo: TicketInfoType//工单信息
}>()

const emit = defineEmits<{
    (e: 'success'): void
}>()

const { hideKeyboard } = useKeyboard()

const visible = computed(() => {
    return Number(localStorage.getItem('mobile_userType'))
})

const ticketNumber = computed(() => {
    return Number(route.query.id)
})

const showPopup = defineModel<boolean>('modelValue')

const route = useRoute()

const activeTab = ref(0);

const currentDate = ref([]);

const currentTime = ref(['23', '59', '59']);

const minDate = ref(new Date());

const maxDate = ref();

const contactsShow = ref(false)

const showPicker = ref(false)

const workTypeShow = ref(false)

const detailShow = ref(false)

const formRef = ref()

const parameter = ref('')

const commonlyId = ref('')

const radioId = ref('')

const commonlyListId = ref<string[]>([])

//cc下拉数据
const ccSelect = ref<CommonlyType[]>([])


const resetForm = (): EditAddType => {
    return {
        to_user: '', //TOid
        to_username: '', //TO名称
        cc_users: [], //CCid
        cc_users_name: '', //CC名称
        due_time: '', //截至时间
        trust_ref_no: '', //TRUST编号
        reason_type: null, //原因类别id
        reason_type_name: '', //原因类别名称
        comment: '', //说明
        scores: null, //评分
        appraise: '', //留言
        is_public: 0, //公开范围
        attachment: [] //附件
    }
}

const form = ref(resetForm())

//原因类别下拉数据
const causeSelectActions = [
    { text: '软件', value: 0 },
    { text: '硬件', value: 1 },
    { text: '其他', value: 2 },
];

const scoresName = {
    1: '非常不满意',
    2: '不满意',
    3: '一般',
    4: '满意',
    5: '非常满意',
}

const uploadType = [
    '.docx',
    '.xlsx',
    '.pptx',
    '.txt',
    '.pdf',
    '.jpg',
    '.png',
    '.zip',
    '.xls',
    '.xlsm',
    '.doc',
    '.docm',
    '.ppt',
    '.pptm',
    '.pps'
]

// to，cc点击
const toClick = (value: string) => {

    contactsShow.value = true

    parameter.value = value

    commonlyId.value = radioId.value || ''

    commonlyListId.value = ccSelect.value.map((item: any) => item.id) || []
}

//单选事件
const radioChange = (val: CommonlyType) => {
    form.value.to_user = val.username

    form.value.to_username = val.name

    radioId.value = val.id
}

//多选事件
const checkboxChange = (contactsList: CommonlyType[]) => {
    ccSelect.value = contactsList || []

    form.value.cc_users_name = contactsList.map((item: CommonlyType) => item.name).join(',')

    form.value.cc_users = contactsList.map((item: CommonlyType) => item.username)
}

//计算时间显示十分
const computedTime = (type: string): string => {
    if (type === 'hour') {
        if (currentDate.value.join('-') === dayjs().format('YYYY-MM-DD')) {
            return dayjs().format('HH')
        } else {
            '00'
        }
    } else {
        if (currentDate.value.join('-') === dayjs().format('YYYY-MM-DD')) {
            return dayjs().format('mm')
        } else {
            '00'
        }
    }
}

//选择工单类型
const onSelect = (val: { text: string, value: number }) => {
    form.value.reason_type_name = val.text

    form.value.reason_type = val.value
}

//截至时间弹窗
const openPopup = () => {

    currentDate.value = []

    currentTime.value = ['23', '59', '59']
}

//打开弹窗
const openForm = () => {
    if (!prop.statusType) {
        addForm(prop.btnType)
    }

    detailShow.value = true

    // 确保每次打开表单时滚动到顶部
    nextTick(() => {
        scrollToTop()
    })
}

//详情新增数据回显
const addForm = (data: ButtonType) => {
    // to回显数据
    if (data.init_data.to && Object.keys(data.init_data.to).length) {
        form.value.to_user = data.init_data?.to?.username
        form.value.to_username = data.init_data?.to?.name
    }

    // cc回显数据
    ccSelect.value = data.init_data?.cc

    form.value.cc_users = data.init_data?.cc.map((item: CommonlyType) => item.username)

    form.value.cc_users_name = data.init_data?.cc.map((item: CommonlyType) => item.name).join(',')

    // 截至时间
    form.value.due_time = data.init_data?.due_time ? dayjs(data.init_data?.due_time).format('YYYY-MM-DD HH:mm:ss') : ''

    // TRUST编号
    form.value.trust_ref_no = data.init_data?.trust_ref_no

    // 原因类别
    form.value.reason_type = data.init_data?.reason_type
}

// 文件上传
const afterRead = async (uploadFile: any) => {

    if (form.value.attachment.length >= 5) {
        showFailToast('最多上传5个文件')
        return
    }

    //  文件大小不能超过 10MB
    const isLt2M = uploadFile.file.size ? uploadFile.file.size / 1024 / 1024 <= 10 : true

    //上传文件是否包含.
    const Suffix = uploadFile.file.name.includes('.')

    //取文件后缀
    const fileSuffix = uploadFile.file.name.split('.')[uploadFile.file.name.split('.').length - 1].toLowerCase()

    // 不支持上传的文件类型
    const notSupportedType = uploadType.includes('.' + fileSuffix)

    if (!isLt2M) {
        showFailToast('上传文件大小不能超过 10MB!');
        return
    } else if (!notSupportedType || !Suffix) {
        showFailToast('不支持上传该文件类型');
        return
    }

    const nativeFile: File = uploadFile.file as unknown as File

    const res: any = await workAttachmentUpload({ file_name: nativeFile.name, type: nativeFile.type })

    const params = {
        uid: nativeFile.lastModified,
        file_name: nativeFile.name,
        file_path: res.file_path
    }

    form.value.attachment.push(params)

    const xhr = new XMLHttpRequest()

    xhr.open('PUT', res.upload_url, true)

    xhr.setRequestHeader('Content-Type', nativeFile?.type as string)

    xhr.send(nativeFile)
}

//附件下载
const previewFile = async (items: any) => {

    const file: any = form.value.attachment.find((item: any) => item.uid === items.uid)

    const params = {
        file_path: file.file_path,
        file_name: file.file_name
    }

    const res: any = await workAttachmentDownload({ file_path: params.file_path })

    download(res.download_url, params.file_name)

}

//删除附件
const deleteFile = (path: string) => {
    form.value.attachment = form.value.attachment.filter((item: any) => item.file_path !== path)
}

//清空所有表单选项
const clearForm = () => {
    formRef.value?.resetValidation()

    formRef.value?.scrollToField()

    form.value = resetForm()

    radioId.value = ''

    ccSelect.value = []

    form.value.cc_users = []
}

//截至时间确认按钮
const onConfirm = () => {
    form.value.due_time = dayjs(currentDate.value.join('-') + ' ' + currentTime.value.join(':')).format('YYYY-MM-DD HH:mm:ss')
    showPicker.value = false
};

// 表单提交
const onSubmit = async () => {

    try {
        for (let param of form.value.attachment) {
            delete param.uid
        }
        if (!visible.value) {
            form.value.is_public = null
        }

        const params = {
            ...form.value,
            ticket_number: route.query.id,
            operation: prop.btnType.name
        }

        const res: any = prop.statusType ? await workSure(params) : await workOrderSure(params)

        if (res.statusCode === 200) {
            showPopup.value = false

            emit('success')

            showSuccessToast(res.message);
        }
    } catch (err) {
        //
    }
};

// 页面滚动时关闭键盘
const handleTouchMove = () => {
    hideKeyboard()
}

// 滚动到顶部
const scrollToTop = () => {
    const detailForm = document.querySelector('.detailForm')
    if (detailForm) {
        detailForm.scrollTop = 0
    }
}

defineExpose({
    clearForm
})

</script>

<style lang="scss" scoped>
.btn-form {

    .left-uploader {
        padding-left: 35px;
    }

    .list-item-rate {
        display: flex;
        align-items: center;
    }

    .scores-title {
        font-size: 12px;
        text-align: center;
    }

    .work-uploader {
        width: 60px;
        height: 25px;
        background: #d9d9d9;
        text-align: center;
        line-height: 25px;
        border-radius: 10px;
        font-size: 12px;
        font-weight: 600;
        margin-top: 2px;
    }

    .work-file {
        width: 100%;
        display: flex;
        align-items: center;
        font-size: 14px;
        margin-top: 10px;
        padding-left: 120px;

        .work-file-name {
            width: 180px;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
    }


    :deep(.van-nav-bar__title) {
        font-size: 15px;
    }

    :deep(.van-form) {
        .van-cell-group {
            .van-cell {

                .van-field__label--required:before {
                    margin-left: -7px;
                }
            }
        }
    }
}

// :deep(.van-popup) {
//     // height: 100vh;
// }

:deep(.detailForm) {
    height: calc(var(--vh, 1vh) * 100 - 50px);
    overflow: auto;
}
</style>